/******************************************************************************
* This file is part of is32p218 platform,
* Copyright (c) 2009 HangZhou InfoStrong CO.,LTD. All rights reserved.
* This software may only be used under the terms of a valid, current,
* end user license from InfoStrong.
* Nothing else gives you the right to use this software.   
*
* Name:   os_task.h
* Desc:   
* Author: Jerry
* Date:   2009-9-15
* Note:   
* History:
*
******************************************************************************/
#include "isOS.h"
#include "os_cfg.h"

#ifndef __OS_TASK_H__
#define __OS_TASK_H__

#ifdef __cplusplus
extern "C" {
#endif



#define  OS_EXIT_AND_DELETE_TASK       1

  //-- Task states

#define  TSK_STATE_RUNNABLE   0x01
//#define  TSK_STATE_RDY        0x02
#define  TSK_STATE_WAIT       0x04
#define  TSK_STATE_SUSPEND    0x08
#define  TSK_STATE_WAITSUSP   (TSK_STATE_SUSPEND | TSK_STATE_WAIT)
#define  TSK_STATE_DORMANT    0x10

    //--- Waiting
#define  TSK_WAIT_REASON_SLEEP            0x0001
#define  TSK_WAIT_REASON_SEM              0x0002
#define  TSK_WAIT_REASON_EVENT            0x0004
#define  TSK_WAIT_REASON_DQUE_WSEND       0x0008
#define  TSK_WAIT_REASON_DQUE_WRECEIVE    0x0010
#define  TSK_WAIT_REASON_MUTEX_C          0x0020          //-- ver 2.x
#define  TSK_WAIT_REASON_MUTEX_C_BLK      0x0040          //-- ver 2.x
#define  TSK_WAIT_REASON_MUTEX_I          0x0080          //-- ver 2.x
#define  TSK_WAIT_REASON_MUTEX_H          0x0100          //-- ver 2.x
#define  TSK_WAIT_REASON_RENDEZVOUS       0x0200          //-- ver 2.x
#define  TSK_WAIT_REASON_WFIXMEM          0x2000


	// Task's constant information
typedef struct _isOS_TskInfo
{
	void (*task_func_addr)(void *);    	//-- task function
	void * task_func_param;   	//-- task function parameter
	
	isOS_U32 * stk_end;        //-- End address of task's stack space ( Bottom address )
	isOS_S32   stk_size;       //-- Task's stack size (in sizeof(void*),not bytes)
	
#if OS_TSK_NAME_EN
	isOS_S8 *pname;				  //-- Task Name 
#endif
	isOS_S8  cre_priority;       //-- Task create priority

}isOS_TskInfo;

//----- Task Control Block ------------
typedef struct _isOS_TCB
{
   isOS_U32 * task_stk;  //-- Pointer to task's top of stack
   LIST_QUE task_queue;    //-- Queue is used to include task in ready/wait lists
   LIST_QUE timer_queue;   //-- Queue is used to include task in timer(timeout,etc.) list
   LIST_QUE block_queue;   //-- Queue is used to include task in blocked task list only
                               // uses for mutexes priority seiling protocol
   LIST_QUE create_queue;  //-- Queue is used to include task in create list only
   LIST_QUE mutex_queue;   //-- List of all mutexes that tack locked  (ver 2.x)
   LIST_QUE * pwait_queue; //-- Ptr to object's(semaphor,event,etc.) wait list,
                               // that task has been included for waiting (ver 2.x)
   struct _isOS_TCB * blk_task; //-- Store task,that blocked our task(for mutexes's
                               // priority ceiling protocol only (ver 2.x)

   const isOS_TskInfo *ptsk_info;		// Task constant information

   isOS_S32  id_task;             //-- ID for verification(is it a task or another object?)
                               // All tasks have the same id_task magic number (ver 2.x)

   isOS_S8  base_priority;       //-- Task base priority  (ver 2.x)
   isOS_S8  priority;            //-- Task current priority

   isOS_U16  task_state;          //-- Task state
   isOS_S32  task_wait_rc;        //-- Waiting return code(reason why waiting  finished)
   isOS_U16  task_wait_reason;    //-- Reason for waiting

   isOS_U16  tslice_count;        //-- Time slice counter
   isOS_S32  tick_count;          //-- Remaining time until timeout

   isOS_S32  ewait_pattern;       //-- Event wait pattern
   isOS_S32  ewait_mode;          //-- Event wait mode:  _AND or _OR

   void * data_elem;         //-- Store data queue entry,if data queue is full

   isOS_S32  wakeup_count;        //-- Wakeup request count - for statistic
   isOS_U16  activate_count;      //-- Activation request count - for statistic
   isOS_U16  suspend_count;       //-- Suspension count - for statistic

// Other implementation specific fields may be added below

}isOS_TCB;



/*-----------------------------------------------------------
 * Functions of SCHEDULER CONTROL 
 *----------------------------------------------------------*/
void isOS_SchedulerStart( void );
void isOS_CrSchedule( void );
void isOS_TickIncrement( void );

/*-----------------------------------------------------------
 * Functions of Utility
 *----------------------------------------------------------*/

isOS_S32 isOS_TaskCreate(isOS_TCB * task,             	//-- task TCB
                 const isOS_TskInfo *ptsk_info,		   //-- Task's constant information, in create routine
                 isOS_S32 option                       //-- Creation option
                 );
isOS_S32 isOS_TaskSuspend(isOS_TCB * task);
isOS_S32 isOS_TaskResume(isOS_TCB * task);
isOS_S32 isOS_TaskSleep(isOS_U32 timeout);
isOS_S32 isOS_TaskWakeup(isOS_TCB * task);
isOS_S32 isOS_TaskActivate(isOS_TCB * task);
isOS_S32 isOS_TaskReleaseWait(isOS_TCB * task);
void isOS_TaskExit(isOS_S32 attr);
isOS_S32 isOS_TaskTerminate(isOS_TCB * task);
isOS_S32 isOS_TaskDelete(isOS_TCB * task);
isOS_S32 isOS_TaskChangePriority(isOS_TCB * task, isOS_S32 new_priority);
isOS_S32 isOS_TaskTsliceTicks(isOS_S32 priority,isOS_S32 value);

void  isOS_TickIncrement( void );
isOS_U32 isOS_TickCountGet( void );
isOS_U32 isOS_TimeSecondGet( void );
void isOS_TimeSecondSet( isOS_U32 second );

  //-- Routines
void task_wait_scan( isOS_U32 curOSTick );
void task_set_dormant_state(isOS_TCB* task);
void task_to_non_runnable(isOS_TCB * task);
void task_to_runnable(isOS_TCB * task);
isOS_S32  task_wait_complete(isOS_TCB * task,isOS_S32 tqueue_remove_enable); //-- v. 2.3
void task_curr_to_wait_action(LIST_QUE * wait_que,isOS_S32 wait_reason,
                                                    isOS_U32 timeout);
isOS_S32 change_running_task_priority(isOS_TCB * task, isOS_S32 new_priority);
isOS_S32 set_current_priority(isOS_TCB * task, isOS_S32 priority);
void find_next_task_to_run(void);

#ifdef __cplusplus
}
#endif

#endif /* __OS_TASK_H__ */


